/**************************************************************
                       fpc/clam/batch.c
***************************************************************/
#include <stdio.h>
#include <malloc.h>
#include "clam.h"
#include <sys/types.h>
#include <sys/wait.h>
#include <glib.h>
#include "mtp.h"
#include "bss.h"

extern BOOL okaytowrite;
char clientIP[20]="";

extern void Pz_init(),  getdatehead();
extern int loadCz(), fppFindClone(), readfpc();
extern void Zbuild_batch(), Zpace_batch(), Zace_batch(), Zmerge_batch();
extern void mergeGSChandler(FILE *infile);
extern int save_fpc();
extern void Pz_default();
extern void updatecor();
extern void keyset2fpc();
extern void Zclear_chrmsg();
extern void ZprocessSD();
extern void ZCtgChrAll();
extern int save_fpc_safe();
extern void mergeMremHandler();

extern int Num_threads;
char num_procs[20];

#define MAXSEQDIR 30
#define MAXBLASTOUTFILE 30
#define MAXMINLET 7
#define MAXPARMSTRING 50
extern char qryDir[MAXSEQDIR+1];
extern char dbDir[MAXSEQDIR+1];
extern char qryFile[MAXSEQDIR+1];
extern char dbFile[MAXSEQDIR+1];
extern char qrySuffix[MAXSEQDIR+1];
extern char dbSuffix[MAXSEQDIR+1];
extern char blastoutfile[MAXBLASTOUTFILE+1];
extern char xtraParm[MAXPARMSTRING+1];
extern char cutoff_str[100];
char batch_bss_file[MAXPATHLEN];
extern int activekids;
extern int stopblast;
extern int save_output_flag;
extern int clones_matched, clones_not_matched;
extern int activekids;
extern int batch_update_db;
extern int split_bss_flag;

extern int batch, minolap, minId, minHitLenPer, input_ctg;
extern char bssFileLoad[];
extern char seq_name[]; 
extern void order_seqctgs();
extern void do_search(parsetype type, int ctg, int from_end);

extern int format_dbases();
extern void replaceMrksBatch(char* file);

static int nameZfpc();
static int open_fpc();
static void do_summary();
static void do_updcor();
static void do_mergerem(char *remarkFile);
static void do_mergemrkrem();
static void do_webupdate();
//static int get_mtp_args(int argc, char *argv[], gint *min_olap, gint *max_olap,
//                        guint *min_shared, guint *min_unique, gint *shared_weight, gint *unacc_weight, gint *spanmis_weight);
void batch_help();

extern void find_pairs_callback();
extern void save_pairs_file(void);
extern void pick_mtp_clones(void);
extern void write_picked(void);

/*******************************************************************
                     DEF: Zbatch - called by fpp/fpp3.c
******************************************************************/
void Zbatch(int argc, char **argv)
{
int i;
char name[CLONE_SZ];
FILE *fp, *clonefp;
char *lastchar;
double cut=0.0;
char  tmp[15], merge[MAXPATHLEN], dir[MAXPATHLEN], clone_file_name[MAXPATHLEN];
char  remarkFile[MAXPATHLEN];
char  mrkFile[MAXPATHLEN];
char  mrkremFile[MAXPATHLEN];
int tol=0, fpflag=0;
int searchType;
int fromEndVal;
char *pos1, *pos2;
int len;
char str_tmp[MAXPATHLEN], str_ctg[20];
extern char mtp_output_file[MAXPATHLEN];
extern char pair_output_file[MAXPATHLEN];
extern char bssFileText[MAXPATHLEN+1];    
extern int use_fp_pairs; 
extern int use_bss_pairs;
int hicf_mode;

/* one of these have to be set for a given function */
int  sum=0, updcor=0, mergerem=0, mergemrkrem=0,seq=0, kill= -1; /* CAS 29Oct */
int webupdate=0, runbss=0, mergemrk=0, runBuildContigs=0, runMTP=0, runSeqctg = 0;
int bsstool = 0;
//gint min_olap, max_olap, shared_weight, unacc_weight, spanmis_weight;
//guint min_shared, min_unique;
DIR* dirp;
char* ptr;

   fp = stdout;
   name[0] = clone_file_name[0] = dir[0] = merge[0] = remarkFile[0] = '\0';

   for (i=3; i< argc; i++) {

       /* first check for args that don't take a parameter */
       if( strcmp( argv[i], "-help" ) == 0 ) {
            batch_help();
       }
       else if (strcmp(argv[i],"sum")==0) sum=1;      /* provide summary */
       else if (strcmp(argv[i],"updcor")==0) {   /* update cor */
            updcor = 1;
       }
       else if( strcmp( argv[i], "-web" ) == 0 ) {     /* for AGI/AGCoL nightly update */
            webupdate=1;
            printf("Update fpc file for web update.\n");
       }
       else if (strcmp (argv[i], "-s") == 0) {
            SIM_FLAG = 2;
	    fprintf(stdout,"Printing simulation results \n");
       }

       else {
           /* these args all take a parameter */
           if (i+1 >= argc) {
                if (0 == strcmp(argv[i],"bss")){
                    goto bss_error;
                }
                batch_help();
           }
           else if (strcmp(argv[i],"mergerem")==0) {  /* merge clone remark file */
                sscanf(argv[++i], "%s", remarkFile);
                mergerem = 1;
           }
           else if (strcmp(argv[i],"mergemrkrem")==0) { /* merge marker remark file */
                sscanf(argv[++i], "%s", mrkremFile);
                mergemrkrem = 1;
           }
           else if (strcmp(argv[i],"mergemrk")==0) {  /* merge marker file */
                sscanf(argv[++i], "%s", mrkFile);
                mergemrk = 1;
           }
           else if (strcmp(argv[i],"-u")==0) {
                sscanf(argv[++i], "%s", merge);
                fprintf(stdout,"\nBatch merge file %s\n",merge);
           }
           else if (strcmp(argv[i],"-d")==0) {
                sscanf(argv[++i], "%s", dir);
                fprintf(stdout,"Batch Merge directory %s\n",merge);
           }
           else if (strcmp(argv[i],"-n")==0) {         /* compare clone to all others */
                sscanf(argv[++i], "%s", name);
                fprintf(stdout,"Clone %s\n",name);
                fpflag=1;
           }
           else if( strcmp( argv[i], "-f" ) == 0 ) {   /* compare file of clones to all others */
                sscanf(argv[++i], "%s", clone_file_name );
                fprintf(stdout,"file of clones %s\n", clone_file_name );
                fpflag = 1;
           }
           else if (strcmp(argv[i],"-o")==0) {
                i++;
                printf("Write file %s\n",argv[i]);
                if ((fp = fopen(argv[i],"w"))==NULL) {
                   fprintf(stderr, "Error: Cannot open %s\n", argv[i]);
                   exit(0);
                }
           }
           else if (strcmp(argv[i],"-c")==0) {
                sscanf(argv[++i], "%lf", &cut);
                fprintf(stdout,"Cutoff %.0e\n",cut);
           }
           else if (strcmp(argv[i],"-t")==0) {
                sscanf(argv[++i], "%d", &tol);
                fprintf(stdout,"Tolerance %d\n",tol);
           }
           else if (strcmp(argv[i],"-k")==0) {        /* Build contigs */
                sscanf(argv[++i], "%s", tmp);
                if (strcmp(tmp,"n")==0 || strcmp(tmp,"n")==0 || strcmp(tmp,"max")==0)
                   kill = -1;
                else sscanf(tmp, "%d", &kill);
                fpflag=1;
                runBuildContigs=1;
           }
           else if ( strcmp( argv[i], "-p" ) == 0 ) {  /* Build contigs with p threads */
                strcpy(num_procs,argv[++i]);
	        Num_threads = atoi(num_procs);
	        fprintf(stdout,"Creating %d threads\n", Num_threads);
                SHARED_OPTION=1;
                fpflag=1;
                runBuildContigs=1;
           }
           /* jhat  for distributed */
           else if (strcmp(argv[i],"-b")==0) {
                sscanf(argv[++i], "%s", clientIP);
                fprintf(stdout,"Using broadcast IP address %s\n", clientIP);
           }
           else if (strcmp(argv[i],"-x")==0) {        /* this is obsolete Sanger Center stuff */
                sscanf(argv[++i], "%d", &seq);
                fprintf(stdout,"\n");
           }

           else if (strcmp(argv[i],"bss")==0) {            /* for webBSS */
               char inputStr[50];
               runbss = 1;
               if(i+1>=argc) goto bss_error;
               if(sscanf(argv[++i], "%s", inputStr)<1) goto bss_error;
               if(strcmp(inputStr,"-in")){
                   fprintf(stderr,"Incorrect input format.\n");
                   goto bss_error;
               }
               if(i+1>=argc) goto bss_error;
               if(sscanf(argv[++i], "%s", qryDir)<1) goto bss_error;
               if(i+1>=argc) goto bss_error;
               if(sscanf(argv[++i], "%s", inputStr)<1) goto bss_error;
               if(strcmp(inputStr,"-db")){
                  fprintf(stderr,"Incorrect input format.\n");
                  goto bss_error;
               }
               if(i+1>=argc) goto bss_error;
               if(sscanf(argv[++i], "%s", dbDir)<1) goto bss_error;
               if(i+1>=argc) goto bss_error;
               if(sscanf(argv[++i], "%s", inputStr)<1) goto bss_error;
               if(strcmp(inputStr,"-out")){
                  fprintf(stderr,"Incorrect input format.\n");
                  goto bss_error;
               }
               if(i+1>=argc) goto bss_error;
               if(sscanf(argv[++i], "%s", batch_bss_file)<1) goto bss_error;
               
               if(i+1>=argc) goto bss_error;
               if(sscanf(argv[++i], "%s", inputStr)<1) goto bss_error;
               if(strcmp(inputStr,"-e")){
                  fprintf(stderr,"Incorrect input format.\n");
                  goto bss_error;
               }
               if(i+1>=argc) goto bss_error;
               if(sscanf(argv[++i], "%s", cutoff_str)<1) goto bss_error;

			  /* WMN make this parameter optional so not to break WebBSS */
               if(i+1<argc)
			   {
              	 	if(sscanf(argv[++i], "%s", str_tmp)<1) goto bss_error;
               		if(strcmp(str_tmp,"-t")){
                  		fprintf(stderr,"Incorrect input format.\n");
                  		goto bss_error;
               		}
               		if(i+1>=argc) goto bss_error;
               		if(sscanf(argv[++i], "%d", &bsstool)<1) goto bss_error;
			   }
           }
           else if (strcmp(argv[i], "mtp") == 0) {
/* WMN took this out as we aren't automating this anymore. Added the bss/mtp/pair file params **
               int ret;
               ret = get_mtp_args(argc - (i + 1), &(argv[i + 1]),
                                  &min_olap, &max_olap,
                                  &min_shared, &min_unique, &shared_weight, &unacc_weight, &spanmis_weight);
               if (ret >= 0) {
                   runMTP = 1;
                   i += ret + 1;
               }
               else
                   exit(0);
*/
				/* arguments must be in order: bss input file, pairs output file, mtp output file */
				runMTP = 1;
               if(i+1>=argc) goto mtp_error;
               if(sscanf(argv[++i], "%d", &use_bss_pairs)<1) goto mtp_error;
               if(i+1>=argc) goto mtp_error;
               if(sscanf(argv[++i], "%d", &hicf_mode)<1) goto mtp_error;
               if(i+1>=argc) goto mtp_error;
               if(sscanf(argv[++i], "%s", bssFileText)<1) goto mtp_error;
               if(i+1>=argc) goto mtp_error;
               if(sscanf(argv[++i], "%s", pair_output_file)<1) goto mtp_error;
               if(i+1>=argc) goto mtp_error;
               if(sscanf(argv[++i], "%s", mtp_output_file)<1) goto mtp_error;

               
		
           } 
           else if (strcmp(argv[i], "seqctg") == 0) {
             char inputStr[50];
             runSeqctg = 1;
             if((i+9)>argc) goto seqctg_error; 
             sscanf(argv[++i], "%s", inputStr);
             if(strcmp(inputStr, "-bss") == 0)  
               sscanf(argv[++i], "%s", bssFileLoad);
             else 
               goto seqctg_error;
             sscanf(argv[++i], "%s", inputStr);
             if(strcmp(inputStr, "-min") == 0) 
               sscanf(argv[++i], "%d", &minolap);
             else 
               goto seqctg_error;
             sscanf(argv[++i], "%s", inputStr);
             if(strcmp(inputStr, "-hitlen") == 0) 
               sscanf(argv[++i], "%d", &minHitLenPer);
             else 
               goto seqctg_error;
             sscanf(argv[++i], "%s", inputStr);
             if(strcmp(inputStr, "-identity") == 0) 
               sscanf(argv[++i], "%d", &minId);
             else 
               goto seqctg_error;
             printf("bss file %s min olap %d hit len %d indentity %d\n", 
               bssFileLoad, minolap, minHitLenPer, minId); 
           }
           else {
               batch_help();
               exit(0);
           }
        }
   }
   if (name[0] == '\0' && runBuildContigs==0 && seq==0 && merge[0]=='\0' &&
         sum==0 && updcor==0 && mergerem==0 && mergemrkrem==0 && clone_file_name[0] == '\0'
         && runbss==0 && webupdate==0 && mergemrk == 0 && runMTP==0 && runSeqctg==0) {
      batch_help();
      exit(0);
   }

/**** Start processing ****/
   Pz_default(); /* if no header values for sum, bad output */
   Zbatch_flag=1;
                 /* reads Pz values from file */
   if (!open_fpc(argv[1], fpflag)) {
       printf("Abort batch executions\n");
       exit(0);
   }
   if (cut != 0.0) Pz.cutFlt = cut;
   if (tol != 0) {
        Pz.tol = tol;
    }

   if (sum) do_summary();
   else if (updcor) do_updcor();
   else if (mergerem) do_mergerem(remarkFile);
   else if (mergemrkrem) do_mergemrkrem(mrkremFile);
   else if (mergemrk) replaceMrksBatch(mrkFile);         /* files/ace_merge */
   else if (merge[0] != '\0') Zmerge_batch(dir, merge);  /* files/ace_merge */
   else if (name[0] != '\0') {
       if (!nameZfpc(name, fp)) exit(0);
   }
   else if( clone_file_name[0] != '\0') {
       clonefp = fopen(clone_file_name, "r" );
       if( clonefp != NULL ) {
          while( fgets( name, sizeof( name ) - 1, clonefp ) != NULL ) {
                 /* Remove trailing carriage return */
             lastchar = ( char * )(name + strlen( name ) - 1 );
             *lastchar = '\0';
             if( strlen( name ) > 0 ) {
                if( !nameZfpc( name, fp )) {
                   exit( 0 );
                }
             }
          }
          fclose(clonefp);
       }
       else {
          printf( "Could not open %s.\n", clone_file_name );
          printf("Abort batch executions\n");
          exit(0);
       }
   }
   else if (runBuildContigs) Zbuild_batch(kill);
   else if (seq==1 || seq==2) Zpace_batch(fp, seq);
   else if (seq==3 || seq==4 || seq==5) Zace_batch(fp, seq);
   else if (runbss){
      sprintf(xtraParm,"-v 500 -b 500");
      Pz.fromendInt=fromEndVal;
      if((dirp=opendir(qryDir))==NULL && strrchr(qryDir,'/')){
          // it should be a full file path so parse out the dir
          ptr = strrchr(qryDir,'/');
          strcpy(qryFile,ptr+1);
          *ptr = 0;
      } 
      else {
         closedir(dirp);
         strcpy(qryFile,"<all>");
      }     


      strcpy(dbFile,"<all>");

      search_tool_type = (bsstool == 0 ? BLAST : MEGABLAST);
      split_bss_flag = 0;
    
      do_search(searchType,currentctg,fromEndVal);
     
//      sprintf(str_tmp,"rm %s",batch_bss_file);
 //     system(str_tmp);
   }
   else if(webupdate){
      do_webupdate();
   }
   else if (runMTP) {
/* WMN removed for different automation.
       find_pairs(TRUE, FALSE, min_olap, max_olap, min_shared, min_unique);
       find_mtp(shared_weight, unacc_weight, spanmis_weight);
       output_mtp();
*/
		use_fp_pairs = 1;
		find_pairs_callback();
		save_pairs_file();
		pick_mtp_clones();
		write_picked();
		
   } 
   else if (runSeqctg) {
      memset(seq_name, '\0', 50);
      len = strlen(bssFileLoad);
      if(len != 0) {
        if(bssFileLoad[len-1] == '/') {
          printf("Please specify a BSS file in the directory.\n");
          return;
        }
        pos1 = strstr(bssFileLoad, ".bss");
        if(pos1 == NULL) {
          printf("Please specify a BSS file\n");
          return;
        }
        strncpy(str_tmp, bssFileLoad, pos1-bssFileLoad);
        str_tmp[strlen(str_tmp)]='\0';
        pos2 = strrchr(str_tmp, '/');

        if(pos2 != NULL) 
          strcpy(seq_name, pos2+1);
        else 
          strcpy(seq_name, str_tmp);

        seq_name[strlen(seq_name)] = '\0'; 
        pos2 = strstr(pos1+8, ".bss");
        if(pos2 != NULL) { 
          strncpy(str_ctg, pos1+8, pos2-pos1-8);
          input_ctg = atoi(str_ctg);
        } else 
          input_ctg = -1;
      }
      batch = 1;
      order_seqctgs();
   }
   else batch_help();

exit(1);

bss_error:
   fprintf(stderr,"Invalid command line arguments.  Correct format:\n");
   fprintf(stderr,"fpc rice -batch bss -in <query> -db <database> -out <output>  -e <e-value> -t <tool>\ntool=0 for blast, 1 for megablast\n");
   exit(0);

seqctg_error:
   fprintf(stderr,"Invalid command line arguments.  Correct format:\n");
   fprintf(stderr,"fpc rice -batch seqctg -bss <bss file> -min <min olap> \n");
   fprintf(stderr,"-hitlen <hit length> -identity <identity>\n");
   exit(0); 

mtp_error:
	fprintf(stderr,"Missing MTP parameters\n");
	exit(0);
}

/*******************************************************************
                     DEF: nameZfpc
******************************************************************/
static int nameZfpc(char *nameText, FILE *fp)
{
int i, j, cnt;
int index;
struct zzz {
  char name[CLONE_SZ];
  int  n, m;
  double prob;
  int ctg;
} *z, t;
int  max;

  if(!fppFindClone(nameText,&index)) {
      fprintf(stderr,"Error: could not find clone %s\n",nameText);
      return 0;
  }
  if (!loadCz(&C1z, index)) {
      fprintf(stderr, "Error: Failed to load %s\n",nameText);
      return 0;
  }
  fprintf(fp, "\n>> %s %db --> Fpc  (Tol %d, Cutoff %.0e)\n",
                  nameText, C1z.nbands, Pz.tol, Pz.cutFlt);
  max = 100;
  z = (struct zzz *) malloc(sizeof(struct zzz)*max);
  NOMEM3(z, "z", 0);

  for (cnt=i=0; i< arrayMax(acedata); i++)
  {
       if (!loadCz(&C2z, i)) continue;
       if (strcmp(C2z.clone, C1z.clone)==0) continue;
       if (C2z.clone[0]=='!') continue;

        Zsulston(&C1z,&C2z,&Sz);
        if (Sz.prob <= Pz.cutFlt) {
             if (cnt==max) {
                 max += 100;
                 z = (struct zzz *) realloc(z, sizeof(struct zzz)* max);
                 NOMEM3(z, "z", 0);
             }
             strcpy(z[cnt].name, C2z.clone);
             z[cnt].n = C2z.nbands;
             z[cnt].m = Sz.match;
             z[cnt].prob = Sz.prob;
             z[cnt].ctg = C2z.ctg;     /*fred 12/18/02*/
             cnt++;
        }
  }
  for (i=0; i<cnt; i++)
     for (j=i+1; j<cnt; j++)
        if (z[i].prob > z[j].prob) {
           t = z[i];
           z[i] = z[j];
           z[j] = t;
        }
  for (i=0; i<cnt; i++)
          fprintf(fp, "%12s ctg%-5d %2db   %3d %.0e \n",
                 z[i].name, z[i].ctg, z[i].n, z[i].m, z[i].prob);
  fprintf(fp,"Hits %d\n", cnt);
  free(z);
return 1;
}

/******************************************************
              DEF: open_fpc
*****************************************************/
static int open_fpc(char *file, int flag)
{
  int i, j=0, k, leen;
  FILE *fpace;
  BOOL found = FALSE;

  for (leen = i = strlen(file); i>0 && !found; i--)
  {
     if(file[i] == '/'){
       found = TRUE;
       j = i;
     }
  }
  if(found){
     strncpy(dirName,file,j);
     for(k=0, i=j+1;i<leen;i++){
       fileName[k++] = file[i];
     }
     fileName[k] = '\0';
   }
   else strcpy(fileName,file);
   if(strlen(dirName) !=0){
      if((fpace = fopen(messprintf("%s/%s.fpc",dirName, fileName),"r")) == NULL ){
         fprintf(stderr,"Error: %s/%s.fpc does not exist\n",dirName,fileName);
         return 0;
      }
   } else{
      if((fpace = fopen(messprintf("%s.fpc",fileName),"r")) == NULL ){
         fprintf(stderr,"Error: %s.fpc does not exist\n",fileName);
         return 0;
      }
   }
   if(!readfpc(fpace)) {
       fprintf(stderr,"Error: Cannot open %s.fpc\n",fileName);
       return 0;
   }
   if (flag==1) {
      fprintf(stderr,"Load fingerprints\n");
      if (fpRead() == -1) {
          fprintf(stderr,"Error: No cor file - no analysis\n");
          return 0;
      }
   }
return 1;
}

/**************************************************************/
static void do_summary()
{
CLONE *clp;
int i, j, k;
int ctg1=0, ctg2=0, dist=0, seqctg=0, seqclone=0,
     totseqdist=0, totseq=0, totclone=0, totctg=0, totdist=0;
int cancelled=0;
int B=Proj.avgbandsize;
char msg[1000];
double d;
int  found, bin[12], qbin[12];
int  cati[12]={3,10,25, 50, 100, 200, 400, 600, 800, 1000, 1000};

  getdatehead(msg);
  printf("\nFPC %s %s\n\n",fileName, msg);

                /* go through clones */
  seqclone=ctg1=ctg2=cancelled=0;
  for(i=0;i<arrayMax(acedata); i++)
  {
    clp =  arrp(acedata, i, CLONE);
    if (clp->clone[0] == '!' || clp->fp==NULL) cancelled++;
    else {
       if (clp->marker != NULL) ctg1++;
       if (clp->ctg!=0) ctg2++;
       if (IsSeq(clp)) seqclone++;
    }
  }
  printf("Fingerprinted    %d\n", arrayMax(acedata)-cancelled);
  printf("In a contig      %d\n",ctg2);
  printf("Contains markers %d\n", ctg1);
  printf("Picked For Seq   %d\n\n", seqclone);

               /* go through contigs */
  for (k=0; k<10; k++) bin[k]=qbin[k]=0;
  for (i=1; i <= max_contig; i++)
  {
       if (contigs[i].count==0) continue;
       if (NoSum(i)) continue;

        if (contigs[i].right < 0 )
            dist = abs(contigs[i].left) - abs(contigs[i].right) + 1;
        else  dist = contigs[i].right - contigs[i].left + 1;

        if (contigs[i].seq > 0) {
             int left=INT_MAX, right=INT_MIN;
             for (j=contigs[i].start; j != -1; j = clp->next)
             {
                clp = arrp(acedata,j,CLONE);
                if (IsSeq(clp)) {
                    left = MiN(left,clp->x);
                    right = MaX(right,clp->y);
                }
             }
             if (left != INT_MAX) {
                totseq += (right - left +1);
                totseqdist += dist;
                seqctg++;
             }
         }
        totctg++;
        totdist += dist;
        totclone += contigs[i].count;

        for (found=k=0; k< 10 && !found; k++)
          if (contigs[i].count < cati[k]) {
                found=1;
                bin[k]++;
                if (contigs[i].ctgQs > Pz.DQnumq) qbin[k]++;
          }
        if (!found) { /* > 1000 */
            bin[k]++;
            if (contigs[i].ctgQs > Pz.DQnumq) qbin[k]++;
        }
  }
  if (totctg!=0)
    printf("Contigs %d  AvgCloPerCtg %d\n",
                     totctg, totclone/totctg);
  if (seqctg!=0)
    printf("SeqCtgs %d  AvgSeqPerSeqCtg %d\n\n",
                     seqctg,  seqclone/seqctg);

  d = ((float) totdist * (float) B) / 1000.0;
  printf("Total    Contig Coverage %d kb\n", (int) d);
  d = ((float) totseqdist * (float) B) / 1000.0;
  printf("Sequence Contig Coverage %d kb\n", (int) d);
  d = ((float) totseq * (float) B) / 1000.0;
  printf("Total Sequence  Coverage %d kb\n", (int) d);
  printf("\nRange     Contigs  Qcontigs\n");
  for (i=9; i>=0; i--) {
     if (i==9) printf("INF:%4d  %6d  %6d\n",cati[i],bin[i],qbin[i]);
     else      printf("%3d:%4d  %6d  %6d\n",cati[i+1]-1,cati[i],
                           bin[i],qbin[i]);
  }
}

/**************************************************************/
static void do_updcor()
{
  updatecor();
}

/**************************************************************/
static void do_mergerem(char *remarkFile)
{
  FILE *remfile;

  remfile = fopen(remarkFile, "r");
  if (remfile == NULL) return;

  mergeGSChandler(remfile);

  fclose(remfile);

  okaytowrite = 1;
  save_fpc();
}
/**************************************************************/
static void do_mergemrkrem(char *remarkFile)
{
  FILE *remfile;

  remfile = fopen(remarkFile, "r");
  if (remfile == NULL) return;

  mergeMremHandler(remfile);

  fclose(remfile);

  okaytowrite = 1;
  save_fpc();
}

/*********************
 fred 12/10/02
 1. Put all sd singleton clones in keyset.
 2. AutoAdd keyset->fpc (at 1e-10)
 3. Clear contig remarks
 4. Chr->Ctg Process sd clones
 5. Assign ctg->chr
*********************/
static void do_webupdate(){
  CLONE *c;
  struct list *p=NULL;
  int i,j,max;
  BOOL found;

  /* Step 1.*/
  classctg = CLONECLASS;
  listroot=NULL;
  if (acedata==NULL) return;
  max = arrayMax(acedata);
  found = FALSE;
  for (j=0; !found && j<max; j++){ /* cari 12/19/03 */
        c=arrp(acedata,j,CLONE);
        if((strstr(c->clone,"sd")!=NULL) && (c->ctg == 0)){
          listroot  = (struct list *)messalloc((sizeof(struct list)));
          listroot->index = j;
          listroot->next = NULL;
          p = listroot;
          found = TRUE;
        }
  }
  for(i=j;i<max;i++){
        c=arrp(acedata,i,CLONE);
        if((strstr(c->clone,"sd")!=NULL) && (c->ctg == 0)){
           p->next  = (struct list *)messalloc((sizeof(struct list)));
           p=p->next;
           p->index= i;
        }
  }
  if(p!=NULL) p->next = NULL;
  if (listroot==NULL) return;

  /*Step 2.*/
  Pz.tol=7;
  Pz.cutFlt=1e-10;
  Pz.autoaddFlag=1;
  fpRead();
  keyset2fpc();

  /*Step 3. cari 10apr05
  Zclear_chrmsg(); */

  /*Step 4.*/
  ZprocessSD();

  /*Step 5.*/
  ZCtgChrAll();

  save_fpc_safe();
}
void batch_help()
{
          fprintf(stdout,"Usage: fpc project -batch [args]\n");
          fprintf(stdout,"   The following functions are not prefixed with '-'\n");
          fprintf(stdout,"       updcor                  update .cor\n");
          fprintf(stdout,"       sum                     Gives a summary\n");
          fprintf(stdout,"       web                     Run Keyset->FPC on SD, Process SD, Ctg->Chr\n");
          fprintf(stdout,"       bss                     Type fpc project -batch bss for details\n");
          fprintf(stdout,"       mergerem    <filename>  Merge clone remarks\n");
          fprintf(stdout,"       mergemrkrem <filename>  Merge marker markers\n");
          fprintf(stdout,"       mergemrk    <filename>  Replace markers\n");
          fprintf(stdout,"   Using the following parameters  runs Replace markers, \n");
          fprintf(stdout,"            but also loads 'framework' and 'sequencenew.ace' if they exist\n");
          fprintf(stdout,"       -u ace file [e.g. marker.ace]\n");
          fprintf(stdout,"       -d complete directroy path [default fpc directory, sub-dir 'update' ]\n");

          fprintf(stdout,"   Parameters for clone name analysis\n");
          fprintf(stdout,"       -n clonename\n");
          fprintf(stdout,"       -o output file [default stdout]\n");
          fprintf(stdout,"       -f file of clone names\n" );
          fprintf(stdout,"   Parameters for Build Contigs\n");
          fprintf(stdout,"       -k maximun sized contig to kill [use -1 for maximum size]\n");
          fprintf(stdout,"       -p number of threads to use for Shared Memory Machines\n");
          fprintf(stdout,"       Note: use one or both parameters\n");
          fprintf(stdout,"   Parameters for any option calulating the Suston core\n");
          fprintf(stdout,"       -c cutoff [default from project fpc file]\n");
          fprintf(stdout,"       -t tolerance [default from project fpc file]\n");
          fprintf(stdout,"   Parameter for simulation results \n");
          fprintf(stdout,"       -s Results of 1e,2e,3e,4e,5e digestion techniques\n");
          fprintf(stdout,"       Will be output in the file results.txt\n");

          fprintf(stdout,"   Parameter to dump clones\n");
          fprintf(stdout,"       -x digit where digit is\n");
          fprintf(stdout,"          3 all contigs\n");
          fprintf(stdout,"          4 sequenced contigs\n");
          fprintf(stdout,"          5 clones with bands\n");
          fprintf(stdout,"       -o output file [default stdout]\n\n");
          fprintf(stdout,"   Errors go to stderr and exit(0)\n");
          fprintf(stdout,"   Other FPC output and batch args go to stdout\n\n");

          exit(0);
}

//#define G_MAXINT 0x7FFFFFFF
//#define G_MININT 0x80000000
//#define G_MAXUINT 0xFFFFFFFF

/*
// get_mtp_args
//
// Parse mtp batch command line arguments, and set appropriate
// variables.
//
// Note: when macro MIN_UNIQUE_PAR is defined at compile time, its
// value is used to set the "min_unique" variable; otherwise,
// "min_unique" is a command line flag whose value gives the value of
// "min_unique".
//
// Return:
//  Number of arguments processed, or -1 on error.
//
static int
get_mtp_args(int argc, char *argv[], gint *min_olap, gint *max_olap,
             guint *min_shared, guint *min_unique, gint *shared_weight, gint *unacc_weight, gint *spanmis_weight)
{
    gchar min_olap_flag[] = "-min_olap";
    gchar max_olap_flag[] = "-max_olap";
    gchar min_shared_flag[] = "-min_shared";
#ifndef MIN_UNIQUE_PAR
    gchar min_unique_flag[] = "-min_unique";
#endif
    gchar shared_weight_flag[] = "-shared_weight";
    gchar unacc_weight_flag[] = "-unacc_weight";
    gchar spanmis_weight_flag[] = "-spanmis_weight";

    enum {FLAG, UINT, INT} next_par;
    union {guint *u; gint *d;} next_value;
    guint i;
    int result = 0;
    int ret;

    *min_olap = G_MAXINT;
    *max_olap = G_MININT;
    *min_shared = G_MAXUINT;
#ifndef MIN_UNIQUE_PAR
    *min_unique = G_MAXUINT;
#else
    *min_unique = MIN_UNIQUE_PAR;
#endif
    *shared_weight = G_MAXINT;
    *unacc_weight = G_MAXINT;
    *spanmis_weight = G_MAXINT;

    next_par = FLAG;
    for (i = 0; result >= 0 && i < argc; ++i) {
        switch (next_par) {
        case FLAG:
            if (strncmp(argv[i], min_olap_flag,
                        sizeof(min_olap_flag) - 1) == 0) {
                next_par = INT;
                next_value.d = min_olap;
                ++result;
            }
            else if (strncmp(argv[i], max_olap_flag,
                             sizeof(max_olap_flag) - 1) == 0) {
                next_par = INT;
                next_value.d = max_olap;
                ++result;
            }
            else if (strncmp(argv[i], min_shared_flag,
                             sizeof(min_shared_flag) - 1) == 0) {
                next_par = UINT;
                next_value.u = min_shared;
                ++result;
            }
#ifndef MIN_UNIQUE_PAR
            else if (strncmp(argv[i], min_unique_flag,
                             sizeof(min_unique_flag) - 1) == 0) {
                next_par = UINT;
                next_value.u = min_unique;
                ++result;
            }
#endif
	    else if(strncmp(argv[i], shared_weight_flag,
			     sizeof(shared_weight_flag) - 1) == 0) {
		next_par = INT;
		next_value.d = shared_weight;
                ++result;
	    }
	    else if(strncmp(argv[i], unacc_weight_flag,
			     sizeof(unacc_weight_flag) - 1) == 0) {
		next_par = INT;
		next_value.d = unacc_weight;
                ++result;
 	    }
	    else if(strncmp(argv[i], spanmis_weight_flag,
			     sizeof(spanmis_weight_flag) - 1) == 0) {
		next_par = INT;
		next_value.d = spanmis_weight;
                ++result;
 	    }
            else {
                fprintf(stderr, "Invalid option flag: '%s'.\n", argv[i]);
                result = -1;
            }
            break;
        case UINT:
            ret = sscanf(argv[i], "%u", next_value.u);
            if (ret == 1) {
                next_par = FLAG;
                ++result;
            }
            else {
                fprintf(stderr,
                        "Invalid unsigned integer value for option '%s'.\n",
                        argv[i - 1]);
                result = -1;
            }
            break;
        case INT:
            ret = sscanf(argv[i], "%d", next_value.d);
            if (ret == 1) {
                next_par = FLAG;
                ++result;
            }
            else {
                fprintf(stderr,
                        "Invalid integer value for option '%s'.\n",
                        argv[i - 1]);
                result = -1;
            }
            break;
        default:
            g_assert_not_reached();
            break;
        }
    }
    if (result >= 0) {
        if (*min_olap == G_MAXINT) {
            fprintf(stderr, "Minimum overlap value (option '%s') is mandatory "
                    "but was not given on command line.\n", min_olap_flag);
            result = -1;
        }
        if (*max_olap == G_MININT) {
            fprintf(stderr, "Maximum overlap value (option '%s') is mandatory "
                    "but was not given on command line.\n", max_olap_flag);
            result = -1;
        }
        if (*min_olap != G_MAXINT && *max_olap != G_MININT &&
            *min_olap > *max_olap) {
            fprintf(stderr, "Invalid overlap parameters: minimum overlap "
                    "value must not exceed maximum overlap value.\n");
            result = -1;
        }
        if (*min_shared == G_MAXUINT) {
            fprintf(stderr, "Minimum shared bands value (option '%s') is "
                    "mandatory but was not given on command line.\n",
                    min_shared_flag);
            result = -1;
        }
#ifndef MIN_UNIQUE_PAR
        if (*min_unique == G_MAXUINT) {
            fprintf(stderr, "Minimum unique shared bands value (option '%s') "
                    "is mandatory but was not given on command line.\n",
                    min_unique_flag);
            result = -1;
        }
#endif
        if (*shared_weight == G_MAXINT) {
            fprintf(stderr, "shared weight value (option '%s') is mandatory "
                    "but was not given on command line.\n", shared_weight_flag);
            result = -1;
        }
        if (*unacc_weight == G_MAXINT) {
            fprintf(stderr, "unaccounted weight value (option '%s') is mandatory "
                    "but was not given on command line.\n", unacc_weight_flag);
            result = -1;
        }
        if (*spanmis_weight == G_MAXINT) {
            fprintf(stderr, "spanner mismatch weight value (option '%s') is mandatory "
                    "but was not given on command line.\n", spanmis_weight_flag);
            result = -1;
        }
    }

    if (result < 0) {
        fprintf(stderr,
                "Usage: fpc <project> -batch mtp -min_olap <minimum overlap> "
                "-max_olap <maximum overlap> "
                "-min_shared <minimum shared bands>");
#ifndef MIN_UNIQUE_PAR
        fprintf(stderr, " -min_unique <minimum unique shared bands>");
#endif
        fprintf(stderr, " -shared_weight <shared weight> "
                "-unacc_weight <unaccounted weight> "
                "-spanmis_weight <spanner mismatch weight> \n");
    }

    return result;
}
*/
